home *** CD-ROM | disk | FTP | other *** search
/ SoundMaker 2003 (Professional Edition) / SoundMaker 2003 - Professional Edition.iso / music workstation / ptwdemo.exe / {app} / ptwdll.txt < prev    next >
Text File  |  2002-04-25  |  43KB  |  903 lines

  1.                 INTERFACING A .DLL or .EXE WITH POWERTRACKS
  2.  
  3. This document applies to both .DLL and .EXE support, even though 
  4. there are minor differences in behavior of .EXEs vs. DLLs. These 
  5. differences, along with information about .EXE support, will be 
  6. discussed later in this document.
  7.  
  8. NOTE: Starting with PowerTracks Version 8.0, only 32-bit .DLLs and
  9. .EXEs can link to PowerTracks.  Any 16-bit .DLL or .EXE programs
  10. need to be recompiled as 32-bit.  Also, 32-bit .DLLs and .EXEs will 
  11. not work with earlier version of PowerTracks.  We suggest you focus 
  12. only on creating 32-bit .EXEs since future versions of PowerTracks 
  13. will be 32-bit only.
  14.  
  15. NOTE: Since a 32-bit .EXE is NOT allowed to pass a pointer directly 
  16. to another 32-bit .EXE, it is now required that you use a Memory 
  17. Mapped File each time the .EXE passes a structure or string to 
  18. PowerTracks.   While this is inconvenient, it is not that 
  19. complicated, and the EXEDEMO.DPR contains sample source code that 
  20. makes it clear how to deal with Memory Mapped Files.   The 
  21. EXEDEMO.ZIP file containing the EXEDEMO project, contains a 
  22. MEMMAP.PAS which can be used to easily create Memory Mapped Files 
  23. as needed.
  24.  
  25. For EXE programs: the rule is that you can NEVER pass anything to
  26. PowerTracks as a pointer, so you have to first create a Memory
  27. Mapped File for the structure you wish to pass.  These Memory
  28. Mapped Files are NOT actual files on disk, but, when created, the
  29. Memory Mapped Files are given names that are used to identify them, 
  30. and you must name them correctly so PowerTracks will recognize 
  31. them.
  32.  
  33.  
  34. If You're using an .EXE, you would create memory mapped files 
  35. within your .EXE using the exact file names discussed later in this
  36. document.  For any message that formerly required a pointer, 
  37. you would pass zero (Nil), since PTW will be use an API call to open for the 
  38. memory mapped file name that is specific to the message you're 
  39. sending to PTW.
  40.  
  41. NOTE REGARDING DLLS: If you are interfacing a .DLL with 
  42. PowerTracks, you do not need to use Memory Mapped Files.  You can 
  43. pass structures directly as pointers in the LParam parameter of 
  44. a SendMessage, and PTW will use those pointers instead of attempting
  45. to open a memory mapped file.  You could use Memory Mapped Files if 
  46. you wanted to with a .DLL but, it would probably be easier to just 
  47. pass pointers directly to the .EXE.
  48.  
  49. For example, if you wish to pass the TExeInfo structure, you create a
  50. Memory Mapped File called 'PTWExeInfo', and this file is equal in
  51. size to the TExeInfoStructure.  Each structure that gets passed to PTW,
  52. will have a corresponding name that must be used when creating the Memory Mapped File
  53. for the structure.
  54.  
  55. Here are a list of the structures and the corresponding names: 
  56. (unless otherwise noted, the file sizes must be set to the sizes of 
  57. the structures)
  58.  
  59. TExeInfo   -->  'PTWExeInfo' is the name used for the Memory Mapped File
  60. TTrackInfo -->  'PTWTrackInfo' is the name used for the Memory Mapped File
  61. TIndexedMIDIData ---> 'PTWIndexedMIDIData' is the name used for the Memory Mapped File
  62. PChar ----> 'PTWString' is the name used for the Memory Mapped File in order
  63. to pass a PChar string (such as a file name, etc.) to PowerTracks.  
  64. This file should be always be 257 bytes in size, regardless of how 
  65. small a string you intend to pass to PTW.
  66.  
  67. For example, when retrieving information about a track in PowerTracks,
  68. you must first create this Memory Mapped File:
  69. ---------------------------------------------------------------
  70. Uses MemMap;
  71.  
  72. Var TrackMemMap:TMemMap; TrackInfo:PTrackInfo;
  73.  
  74.  TrackMemMap := TMemMap.Create('PTWTrackInfo',SizeOf(TTrackInfo));
  75.  If TrackMemMap = Nil then exit;
  76.  TrackInfo := PTrackInfo(TrackMemMap.GetMemPtr);
  77.  
  78.  SendMessage(WinHandle,wm_MD_SetTrackNumber,SpinEdit1.Value,0);
  79.  SendMessage(WinHandle,wm_MD_GetTrackInfo,0,0);
  80. --------------------------------------------------------------
  81. In the Above code, the Memory Mapped File called 'PTWTrackInfo' is created
  82. with a size equal to the size of the TTrackInfoStructure.  The file must be named
  83. exactly as 'PTWTrackInfo' because PowerTracks will look for that file when
  84. the wm_MD_GetTrackInfo or wm_MD_SetTrackInfo commands are received by PowerTracks.
  85. If you are using Memory Mapped Files, you must ALWAYS set the lparam field to zero.
  86.  
  87. NOTE: The structures have changed in that they no longer contain
  88. any embedded pointers.  For example, a structure that contained a
  89. PChar will now contain an array [0..128] of char.  A structure
  90. containing a pointer to an array will now include the actual array.
  91.  
  92. You can use the language of your choice (C++, Pascal, Delphi etc.)
  93. Once created, the .DLL (or .EXE) can be used by PowerTracks, 
  94. and will appear to the user as a button on the Mixer Screen. Inside 
  95. the .DLL (or .EXE), you will have easy access to the MIDI data that 
  96. PowerTracks is receiving and sending out, and will also easily be 
  97. able to send out your own MIDI data to your synthesizer.
  98.  
  99. Examples of possible .DLLs (or .EXEs) that could be created are:
  100. - 'front panel' type functionality for a specific synthesizer.
  101. - editor/ librarian for a synthesizer.
  102. - utility program - MIDI monitor
  103. - displaying MIDI data in a custom format or in a graphical way.
  104. - using MIDI data to trigger graphics etc.
  105.  
  106. ***************************************************************
  107. NOTE: This documentation covers the Programming of .DLLs using
  108. PowerTracks. This is nothing to do with the international language
  109. support .DLLs you can make for other language support like French,
  110. Spanish etc. If you are interested in making an international version
  111. of PowerTracks (or another PG Music program), you'll need different
  112. documentation, please contact us for this.
  113. ****************************************************************
  114.  
  115. When you create the .DLL (or .EXE), you name it starting with a $ 
  116. sign, and put it in the PowerTracks directory c:\pt. When the user 
  117. selects a .DLL (or .EXE), the .DLL and .EXE files with a $ sign 
  118. will appear in the list, and he can choose your .DLL or .EXE. 
  119.  
  120. In the case of a .DLL, once your DLL is chosen, the DLL is run and 
  121. you are passed a structure that contains information like: - the 
  122. Handle of the MIDI Output device that PowerTracks is set to use. 
  123.  
  124. (Interfacing with an .EXE involves sending the wm_MD_EXESignIn to 
  125. obtain the same structure that is passed to .DLLs, and will be 
  126. discussed later in this document.)
  127.  
  128. You can use the output handle immediately inside your .DLL by 
  129. calling the MIDIOutShortMsg routine with the handle, and the 
  130. MIDIData that you want to send out. If your application is only 
  131. sending MIDI out (and not processing input), then this Handle is 
  132. virtually the only piece of information that you need.
  133.  
  134. ************IMPORTANT INFO REGARDING EXE PLUGINS***************
  135. It appears that WinXP doesn't support the sharing of MIDI output 
  136. ports between two different applications, so we created a 
  137. WM_MD_SendShortMsg that lets your .EXE plugin send a MIDI short message
  138. via PowerTracks without your plugin needing to open it's own MIDI 
  139. Output port.  DLL MIDI Plugins can still call MidiOutSHortMsg 
  140. directly.
  141. ****************************************************************
  142.  
  143.  
  144.     - a circular buffer prepared by PowerTracks with all the
  145.     incoming MIDI data that is coming from MIDI thru (that the
  146.     user is playing) as well as the outgoing data that PowerTracks
  147.     is sending. This buffer includes regular MIDI data, as well
  148.     as Sys-EX events. If your application is processing the data
  149.     in this buffer (for a MIDI monitor for example), then it will
  150.     be regularly reading this buffer.
  151.  
  152.  
  153. You can use any language that is capable of compiling to a .DLL or 
  154. .EXE. This includes C,C++, Pascal and Delphi. 
  155.  
  156. The advantages of creating a .DLL (or .EXE) to use in PowerTracks 
  157. are: 
  158.  
  159. - The .DLL or .EXE is easily accessible to the user as it appears 
  160. as a button on the Mixer Window, and via a menu item starting with 
  161. PTW 3.0b.
  162.  
  163. - the .DLL or .EXE uses the same output handle, and input buffer 
  164. as PowerTracks, overcoming the limit of '1 application per driver' 
  165. that many applications have, 
  166.  
  167. - simplifies Windows MIDI programming. You don't need to worry 
  168. about finding the output handle to use, or worry about collecting 
  169. the incoming data in a buffer. This is done for you. 
  170.  
  171. - re-usability. Other PG Music programs (Band-in-a-Box, The Pianist 
  172. may soon support these .DLLs and .EXEs, so that when you create a
  173. .DLL or .EXE for PowerTracks, it will also work for these other 
  174. programs, (NOTE: this is assuming that the .DLL/.EXE doesn't do 
  175. things that are unsupported by the other programs.  For example, 
  176. since the Pianist is not a sequencer it may not support all the new 
  177. editing messages that PowerTracks does.)
  178.  
  179.  
  180. Questions regarding the documentation or DLL/EXE programming
  181.  should be addressed to support@pgmusic.com
  182. *************************************************
  183.  
  184. The following documentation is in Pascal. If using C, you'd need
  185. to convert this Procedure to Pascal.
  186.  
  187. We include a complete sample application called GS Reset, which
  188. compiles to a .DLL. This simple .DLL has a button that resets
  189. a GS synthesizer, and will give you a simple introduction to
  190. the .DLL programming. This GSRESET code is found in the file
  191. GSRESET.ZIP. The GS RESET code is in 'Delphi' , which is the
  192. newest implementation of Pascal for Windows from Borland .
  193.  
  194. We also include a demo exe in EXEDEMO.ZIP, which is a demo .EXE 
  195. written in Delphi with complete source code.
  196.  
  197. A .DLL must have the following procedure, which is called by
  198. PowerTracks:
  199.  
  200. Procedure
  201. LaunchTheDialog(HWindow:Hwnd;TheCurrentPart:Integer;PortHandle:THandle;
  202. TheMIDIInfo:PMIDIInfo;ProgNum,Language:Byte);
  203. Export;
  204.  
  205. You should make sure that the LaunchTheDialog procedure exits
  206. gracefully if is called twice before the first call to the dialog
  207. finished executing.  If you don't do this then there could be 
  208. problems if we added .DLL support to other programs and two 
  209. programs attempted to use the same .DLL at the same exact time.
  210.  
  211. Also, the .DLL should still remain in memory even if the user 
  212. closes the dialog, because PowerTracks will assume the .DLL is 
  213. still active and could call the LaunchTheDialog procedure again
  214. if the user presses the <Run DLL> button.
  215.  
  216. Note: A dialog can show a normal window instead of a dialog when 
  217. the LauchTheDialog procedure is called.  This would let the user 
  218. switch back and forth between the window and PowerTracks while the 
  219. .DLL is loaded.  However, your .DLL should be written in such a way 
  220. that it exits the LaunchTheDialog procedure if called while the 
  221. window is already currently displayed, rather than displaying 
  222. duplicate windows! 
  223.  
  224. The HWindow is a handle to the mixer window of PowerTracks.  This
  225. may be needed if your programming language requires a parent window
  226. to launch a dialog from within a .DLL, or when the .DLL sends a
  227. message to the mixer window such as WM_BufferNotNeeded (explained
  228. below).
  229.  
  230. TheCurrentPart is the current part number or channel number of a 16
  231. part synth.  You can ignore this if the .DLL you're writing isn't
  232. for a specific synth.
  233.  
  234. The PortHandle is a handle to a MIDIOutput port in PowerTracks.  It
  235. is the output port of the current track.  You can use this handle
  236. when calling multimedia API functions such as midiOutShortMsg.
  237.  
  238. TheMIDIInfo is pointer with a type of PMIDIInfo, which is a pointer
  239. to a TMIDIInfo data structure.  The Definition of PMIDIInfo is as
  240. follows:
  241.  
  242. PMIDIInfo = ^TMIDIInfo;
  243.  
  244. TMIDIInfo = Record
  245. TheMIDIEventArray:PMIDIEventArray  {Pointer to a circular buffer array};
  246. MIDIEventHead,MIDIEventTail:Word;  {Head and Tail of buffer}
  247. SysExArray:PSysExArray;  {Pointer to the array of Sysex data}
  248. End;
  249.  
  250. The MIDIEventArray, and SysExArray are two items that are used if a
  251. .DLL needs to receive output message from PowerTracks.  These items
  252. can be ignored by a .DLL or .EXE that doesn't need them.  If a program
  253. doesn't need to use these items it should send a special message to
  254. the handle of the window that was passed in the HWindow parameter
  255. of LaunchTheDialog.  This message is as follows:
  256.  
  257. Const wm_BufferNotNeeded = wm_User + 33;
  258.  
  259. e.g SendMessage(HWindow,wm_user+33,0,0);
  260.  
  261. This tells PowerTracks a .DLL or .EXE won't be using the buffers 
  262. so it doesn't have to waste time filling them.
  263.  
  264. Keep in mind that using these buffers requires that you install a
  265. timer to read them often, such as a WM_TIMER, which may not be
  266. adequate, or preferably a multimedia timer, which is much more
  267. accurate.  Reading and processing these buffers in a .DLL or .EXE 
  268. could possibly take significant time away from PowerTracks to be 
  269. able to do things like redraw screens quickly, etc. so this feature 
  270. may be only desirable on fast 486 or higher machines.
  271.  
  272. The program will keep adding to the buffers in a circular fashion,
  273. so it's the responsibility of the .DLL or .EXE to read the data 
  274. quickly enough not to miss any data.
  275.  
  276. PMIDIEventArray = ^TMIDIEventArray;
  277. TMIDIEventArray = Array [1..1000] of TMIDIEvent
  278.  
  279. TMIDIEventArray is a circular buffer of TMIDIEvents.  A TMIDIEvent
  280. is defined as follows:
  281.  
  282. TMidiEvent = Record
  283. Source:Word;  {0 for thru; 1 for output}
  284. Event:Longint;  {MIDI Event}
  285. End;
  286.  
  287. The source indicates whether the event was a normal output event or
  288. a thru event.
  289.  
  290. The Event field is a long integer storing the MIDI data bytes.  The
  291. most significant byte contains the status, and the 2nd and 3rd most
  292. significant bytes contain the data bytes, and the least significant
  293. byte isn't used.  This is the same structure that is used by
  294. multimedia windows for MIDIOutShortMsg.
  295.  
  296. The PSysExArray is a pointer to a TSysexArray data structure as
  297. shown below:
  298.  
  299. PSysExArray = ^TSysExArray;
  300. TSysexArray = Array[0..64000] of Byte;
  301.  
  302. PowerTracks will fill the SysexArray field with bytes of SysexData and
  303. then fill the  TheMIDIEventArray buffer with two special $F0/$F7 events
  304. that indicate that indicate the position of the beginning and
  305. end of a sysex message.  For example:
  306.  
  307. Source  Event         Interpretation
  308.  
  309. 0       $903C4000     ($90  $3C $40)  Note on Middle C, the source of 0 means
  310.                                       that MIDI thru (i.e. input) was the source of the
  311.                                       message.
  312. 1       $99244000     ($99  $24 $40)  A Drum note was sent out the MIDI output from
  313.                                       PowerTracks (assuming drums are on channel 10)   
  314.                                       (The Source=1 indicates that PTW sent the note out.)
  315. 0       $F0000000     ($F0  $00 $00)  A SysEx message was received 
  316.                                       by PTW from MIDI.
  317.                                       Sysex messages starts at offset $0000
  318. 0       $F7010400     ($F7  $01 $04)  The SysEx message ends at offset $0104 indicating
  319.                                       that the message stored in the sysex is from 0 to $104,
  320.                                       so it is 261 bytes long.
  321. 1       $C1200000     ($C1  $20)      A patch change of 33 was sent out by the program.            
  322.                                       (assuming you consider patch numbers to begin
  323.                                        with 1 and end with 128) 
  324. 0       $F0010500     ($F0  $01 $05)  Another sysex has been stored.
  325. 0       $F7010900     ($F7  $01 $09)  This one ends soon so it is only 5 bytes long.
  326.  
  327. The ProgNum parameter in the LuanchTheDialog procedure tells which 
  328. PG Music program called the .DLL. Currently only PowerTracks 
  329. interfaces with this type of DLL, but this feature could be added 
  330. to the other programs as well.
  331.  
  332. Here are the various possible values for the ProgNum parameter:
  333.  
  334. 0 = Unspecified
  335. 1 = PowerTracks (the only program currently interfacing with these 
  336.                  .DLLs or .EXEs)
  337. 2 = Band-in-a-Box
  338. 3 = Pianist (Classical, New Orleans, or ragtime)
  339. 4 = JazzPianist
  340. 5 = Guitarist
  341. 6  = SC-PRO
  342.  
  343. A .DLL can be loaded, or an .EXE can be launched, when the user 
  344. presses the DLL button in the PowerTracks Mixer window.  All DLLs 
  345. or EXEs in the same directory as PTW.EXE that begin with a dollar 
  346. sign character, e.g. $SC.DLL will appear in a dialog that lets the 
  347. user choose a .DLL or an .EXE.
  348.  
  349. Once a DLL is selected, the LaunchTheDialog Procedure will be 
  350. called by PowerTracks when the user presses the button next to the 
  351. DLL button.  This button will be named 'GS' in the case of $GS.DLL. 
  352. The .DLL will remain loaded in memory until either PTW is finished 
  353. running, or the user selects a different .DLL.
  354.  
  355. (Interfacing with an .EXE involves sending the wm_MD_EXESignIn and 
  356. wm_MD_EXESignOut messages which are discussed later in this 
  357. document.)
  358.  
  359. Additional Messages: Starting with PTW 3.0b, a new set of messages
  360. has been added to expand the capabilities of a .DLL, plus the 
  361. ability to interface with .EXEs was also added to PTW 3.0b.  Since 
  362. many of these messages are appropriate for PowerTracks, only some 
  363. of them may possibly be supported by other programs.  
  364.  
  365. Below are the additional messages, their numeric values will be 
  366. listed at the end of this document.  Each message is listed
  367. here by name.  On the same line as the message name, we'll show
  368. show the usage of each parameter (wParam, lParam, and result), plus 
  369. a description of the message.
  370.  
  371. MESSAGE                 wParam          lParam          Returns
  372.  
  373. wm_MD_GetVersion        not used        not used        version
  374.  (current version is '1'.  If version returned is less than 1, then
  375.  it can be assumed that these messages are not supported, and 
  376.  interfacing with .EXEs isn't supported.) 
  377.  
  378. wm_MD_SetTrackNumber    wTrackNum       not used        Track Number    
  379.  (This sets the track number which will be used when track-related
  380.  messages are sent such as wm_MD_InsertTrackEvent, etc.  You first set
  381.  the track number, and then you can use messages to edit the 
  382.  track.  The wTrackNum can be a number ranging from 1 to the 
  383.  highest track which is returned from the wm_MD_GetHighestTrack 
  384.  message)                   
  385.  
  386. wm_MD_GetTrackNumber    not used        not used        Track Number
  387.  (This returns the track number set with the wm_MD_SetTrackNumber 
  388.  message)
  389.  
  390. wm_MD_GetTrackNumberOfEvents    not used        not used        result
  391.  (This returns the number of events in a track)
  392.  
  393. wm_MD_GetHighestTrack   not used        not used        PTW returns 48
  394.  (This returns the highest track number supported by the program.
  395.   PTW returns 48, since it has 48 tracks)
  396.  
  397. wm_MD_DeleteTrackEvent  not used        dwIndex       result
  398.   (This deletes an event from a track.  Returns 1 for success, 0 
  399.    for failure)
  400.  
  401. wm_MD_UpdateScreens     not used        not used        result
  402.  (This message updates the screens in the program.  You should send
  403.  this message any time you want PTW to update its screens.  For
  404.  example, if you've just did an editing routine, you should send
  405.  this message so that PTW's screens will reflect the changes you've 
  406.  made.)
  407.  
  408. wm_MD_InsertTrackEvent  not used        PIndexedMidiData        result
  409.  (This will insert an event into a track.  The Lparam is a pointer
  410.   to a TIndexedMidiData structure which is as follows:
  411.  
  412.   TIndexedMIDIData = Record
  413.   Index:Longint;  (zero-based index of the event, 1st event has
  414.                   index of zero)
  415.   MIDIData:Longint; (This is the same kind of longint used for
  416.                      MIDI data as Windows 3.1 in functions
  417.                      such as MIDIOutShortMsg.  The least 
  418.                      significant byte is the status, and the
  419.                      2nd and 3rd least significant bytes are
  420.                      used for data bytes 1 and 2.  The most
  421.                      significant byte is not used.  For example
  422.                      a Middle C on channel 1 with a velocity of
  423.                      100 ($90 $3C $64) would be $00643C90. 
  424.                      Keep in mind that PowerTracks stores notes as
  425.                      one event with a duration rather than two separate
  426.                      note on/off events)
  427.       
  428.   Time:Longint;      (This is a time in ticks where 0 is the song 
  429.                       start)
  430.   Duration:Word;     (this is used for the duration if the event is
  431.                       a note)
  432.   LyricText: PChar;  (this is a PChar (pointer to a null terminated 
  433.                       string), and this field is used if the event
  434.                       is a Lyric event $0000007F.  Setting the
  435.                       MIDI data to $0000007F tells PTW that the
  436.                       event is a lyric rather than a MIDI event.
  437.   dw1:Longint;        (not used)
  438.   dw2:Longint;        (not used)
  439.   End;
  440.  
  441. Note: the pointer send in this message must be a valid pointer. You
  442. can use the '@' operator in front of a TIndexedMidiData variable.
  443. For example, if you've got a variable called MyIndexedData that is
  444. a TIndexedMidiData, the LParam field could be Longint(@MyIndexedData).
  445. Typecasting to a longint is necessary since the Lparam field requires
  446. a longint.
  447.  
  448.  
  449. wm_MD_ModifyTrackEvent  not used        PIndexedMidiData        result
  450.  (this is sent to modify an event of a track.  If you change the
  451.   time, the event will be moved to a different location in the
  452.   track according to the time.  All fields in the PIndexedMidiData
  453.   must be set to the correct values for the event even if you're 
  454.   only changing one field for the event.)
  455.  
  456. wm_MD_GetTrackEvent     not used        PIndexedMidiData        result
  457.  (this gets an event from a track and fills the PIndexedMidiData with
  458.   the information about the event)
  459.  
  460. wm_MD_GetTrackInfo      not used        PTrackInfo      result
  461.  (This is used to set track information such as the track name,
  462.   channel, etc.  Msg.LParam is a pointer to a TTrackInfo structure
  463.   which is as follows:
  464.  
  465.    TTrackInfo = Record
  466.    PlayMuteFrozenStatus:Byte; {0 = Frozen, 1 = Muted, 2 = Play)
  467.    Name:PChar; (PChar with the name of the Track.  You MUST make
  468.                 sure this is a valid pointer with enough space
  469.                 allocated for PowerTracks to fill with a track name)
  470.    Channel:Byte; (Forced channel)
  471.    Key:ShortInt; (key transpose)
  472.    Vel:ShortInt; (forced vel +/-)
  473.    Port:Byte;    (port number)
  474.    Patch:ShortInt; (prg number.  -1 thru 127 -- this is always 
  475.                     zero-based with a value of -1 meaning no patch)
  476.    Bank:ShortInt;  (bank number. -1 thru 127)
  477.    Loop:Word;      (loop. 0 thru 999)
  478.    Dw1:Longint;    (unused)
  479.    Dw2:Longint;    (unused)
  480.    w1:Word;        (unused)
  481.    i1:Integer;     (unused)
  482.   End;
  483.  
  484. wm_MD_SetTrackInfo      not used        PTrackInfo      result
  485.  (This sets the track info with the information you've placed into
  486.   a TTrackInfo structure.  LParam is a Pointer to a TTrackInfo
  487.   structure.  All fields must be set even if you're only changing
  488.   one field.)
  489.  
  490. wm_MD_GetSongTime       not used        not used        Song Time in ticks
  491.  (gets current song time in ticks)
  492.  
  493. wm_MD_SetSongTime       not used        dwSongTime      result
  494.  (sets the song time in ticks)
  495.  
  496. wm_MD_Play      not used        not used        result
  497.  (starts playback.  Returns 1 for success, 0 for failure.  Failure
  498.   results if playback is already happening)
  499.  
  500. wm_MD_Stop      not used        not used        result
  501.   (stops playback.  Returns 1 for success, 0 for failure)
  502.  
  503. wm_MD_GetFromValue     not used       not used      FromValue
  504.  (returns from value in ticks)
  505.  
  506. wm_MD_GetThruValue     not used       not used      ThruValue
  507.  (returns thru value in ticks)
  508.  
  509. wm_MD_SetFromValue     not used       dwFromValue      Result
  510.  (Sets from value in ticks, Returns 1 for success, 0 for failure)
  511.  
  512. wm_MD_SetThruValue     not used       dwThruValue      Result
  513.  (Sets thru value in ticks, Returns 1 for success, 0 for failure)
  514.  
  515. wm_MD_IsTrackHighlighted     wTrackNum    not used    Result
  516.  (Used to tell if a particular track is highlighted.  This uses Wparam
  517.  for the track number)
  518.  
  519. wm_MD_GetSongPPQ      not used       not used     SongPPQ
  520.  (Returns PPQ of the song)
  521.  
  522. wm_MD_GetNumberofMeterMapEvents    not used    not used   dwMeterMapEvents
  523.  (Returns number of events in Meter Map)
  524.  
  525. wm_MD_GetMeterMapNumerator      not used       dwIndex      dwNumerator    
  526.  (Returns Numerator of meter map event, or zero for failure)
  527.  
  528. wm_MD_GetMeterMapDenominator   not used       dwIndex      dwDenominator    
  529.  (Returns Denominator of meter map event, or a value <= 0 indicates failure)
  530.  
  531. wm_MD_GetMeterMapTime    not used       dwIndex      dwTime    
  532.  (Returns Time in Ticks of meter map event, or -1 for failure)
  533.  
  534. wm_MD_GetMeterMapMeasure    not used      dwIndex    dwMeasure
  535.   (Returns Measure of meter map event, or -1 for failure)
  536.  
  537. wm_MD_SetMeterMapNumerator     not used    dwIndex      result
  538.  (Sets Numerator of Meter Map event.  Returns 1 for success, 0 for failure)
  539.  
  540. wm_MD_SetMeterMapDenominator     not used    dwIndex      result
  541.  (Sets Denominator of Meter Map event.  Returns 1 for success, 0 for failure)
  542.  
  543. wm_MD_InsertMeter   wMeasure     dwNumeratorDenominator     result
  544.  (Inserts meter map event at measure location in wMeasure (not an index).  
  545.  The high word of dwNumeratorDenominator is the numerator, and the low word 
  546.  is the   denominator.  Result is 1 for success, 0 for failure.  
  547.  Duplicate entries at same measure aren't inserted by this message)
  548.  
  549. wm_MD_DeleteMeter    not used     dwIndex    result
  550.  (This deletes meter map event at dwIndex .  If only 1 meter
  551.  map event exists it won't get deleted.  Returns 1 for success, 0 for failure)
  552.  
  553. wm_MD_GetTempoMapTempoValue   not used     dwIndex   dwTempoValue
  554.  (returns Tempo value of tempo map event)
  555.  
  556. wm_MD_GetTempoMapTime    not used    dwIndex    dwTicks
  557.   (returns time in ticks of tempo map event)
  558.  
  559. wm_MD_SetTempoMapTempoValue     wTempo     dwIndex    Result
  560.   (returns 1 for success, 0 for failure)
  561.  
  562. wm_MD_GetNumberofTempoMapEvents   not used     not used    dwNumberEvents
  563.   (returns number of Tempo Map events)
  564.  
  565. wm_MD_InsertTempo   wTempo   dwTimeInTicks     Result
  566.  (returns 1 for success, 0 for failure.  Will not insert multiple events
  567.   at same time location)
  568.  
  569. wm_MD_DeleteTempo   not used    dwIndex     Result
  570.   (returns 1 for success, 0 for failure.  Will not delete event if it's
  571.   the only tempo map event)
  572.  
  573. wm_MD_GetSongKeySignature    not used    not used    dwKeySigValue
  574.   (returns value representing key signature of song ranging form -7 to 7. 
  575.    The key of C = 0.  Negative  numbers represent flats  (e.g. -1 = f,
  576.    since it has 1 flat, -7 = Cb).  Numbers above zero represent sharps
  577.    (e.g. 1 = G, since the key of G has 1 sharp)
  578.  
  579. wm_MD_SaveUndoTrackData     not used    PChar   result
  580.   (this caused PowerTracks to save the data of all the track so subsequent
  581.    editing can later be 'undone'.  The PChar should be the text 
  582.    that will appear in the PTW Undo menu item after the word, 
  583.    'Undo'.  e.g.  '(Patch Strip)'.  Keep it short in length.  Returns 1 
  584.    for success, 0 for failure)
  585.  
  586. wm_MD_Undo   not used    not used   result
  587.   (This will restore the track data saved with wm_MD_SaveUndoTrackData, if
  588.    any data was saved.  The user can also use the PTW undo so you 
  589.    don't need to provide your own undo if you've send the message 
  590.    to save the undo data.)
  591.  
  592. wm_MD_ExeSignIn  not used    PExeInfo    result
  593.  (This is sent by an .EXE application to 'sign in' to 
  594.   PowerTracks.  This message is number wm_user_258 for the 32-bit
  595.   version of PowerTracks.  Note: It used to be wm_user+240 for the 16-bit 
  596.   version. 
  597.  
  598.   Note: Your application first has to find the main window 
  599.   handle to PowerTracks, but if you're a Delphi programmer, and you 
  600.   use our PGMusicLink component, this is done virtually 
  601.   automatically.  If you're using another language such as C++, you 
  602.   could look at the source code (PGLINK.PAS) and it wouldn't be too 
  603.   difficult to see how our component is able to find PTW's main window
  604.   handle, since Delphi uses the same Windows API calls that other 
  605.   languages use.
  606.  
  607.   An .EXE uses this message to retrieve the same
  608.   information that is retrieved when PTW calls the LaunchTheDialog
  609.   procedure in a .DLL.  The PExeInfo is a pointer to a TExeInfo
  610.   structure, which is:
  611.  
  612.    TEXEInfo = Record 
  613.    HWindow:HWnd;   (handle to main window of PowerTracks)
  614.    TheCurrentPart:Integer;  (current part number.  Actually channel
  615.                              number of current track)
  616.    PortHandle:THandle;  (handle to output port number 1 of PowerTracks)
  617.    TheMIDIInfo:PMIDIInfo;  (Pointer to TMIDIINFO structure, as described
  618.                             earlier in this document.  This must be a
  619.                             valid pointer.  Make sure you don't forget
  620.                             to initialize it.)
  621.    ProgNum,    (ProgNum, as described earlier in this document)
  622.    Language:Byte;   (don't worry about this unless you're planning to
  623.                      support foreign languages.  This number just
  624.                      indicates what language PowerTracks is being used for
  625.                      displaying text.  0 = English,  3 = Chinese, 6 = French,
  626.                      7 = German, 8 = Finnish, 9 = Italian, 10=Japanese,
  627.                      19=Spanish)
  628.     End;
  629.  
  630.    Note: the pointer sent in this message must be a valid pointer. You
  631.    can used the '@' operator in front of a TExeInfo variable. 
  632.    For example, if you've got a variable called MyExeInfo that is
  633.    a TExeInfo, the LParam field could be Longint(@MyExeInfo).
  634.    Typecasting to a longint is necessary since the Lparam field requires
  635.    a longint.
  636.  
  637.    If the Sign In is successful, this message will return 1.  If 
  638.    another .EXE is already signed in, or a .DLL is active it will
  639.    return 0.
  640.  
  641.    Your .EXE should be named beginning with the '$' character, e.g. 
  642.    '$MYEXE.EXE', so that it can be launched from within PTW.
  643.   
  644.  
  645. wm_MD_ExeSignOut      not used    not used    result
  646.   (this causes the currently signed in .EXE to be signed out of PowerTracks.
  647.    Returns 1 for success, 0 for failure.  Do not send this message 
  648.    unless the program is currently successfully signed into PTW.)
  649.  
  650. wm_MD_SaveFile     not used   PCharName    result
  651.   (This will cause PTW to save the current song to the file named 
  652.    in PCharName.  PTW's file name will then be set to that name.
  653.    PCharName must be a valid PChar)
  654.  
  655. wm_MD_LoadFile     not used PCharName   result
  656.   (This will cause PTW to load the file named in PCharName.  
  657.    PCharName must be a valid PChar)
  658.  
  659. wm_MD_GetCurrentFileName not used  PCharName  result
  660. (Returns PTW's current file name by filling PCharName.  PCharName
  661.  must be a valid PChar with at least 80 characters allocated to it)
  662.  
  663. wm_MD_GetCurrentTrack     not used    not used   dwTrackNumber
  664.  (Returns number of the currently selected track in the Tracks 
  665.   Window)
  666.  
  667. wm_MD_IsPlayBackHappening    not used   not used   result
  668.  (returns 1 if playback is happening, or 0 if playback isn't 
  669.   happening)
  670.  
  671. wm_MD_GetOutputPortHandle    wPortNum   not used   dwPortHandle
  672.  (This can be used to obtain the output port handle of ports 1 
  673.   through 16 in PowerTracks.  We added this because only the handle
  674.   to port 1 is obtained during initialization.  wPortNum can be
  675.   a number from 1 through 16.  If you attempt to retrieve the 
  676.   handle of a port that is greater than the max available, but within 
  677.   the 1- 16 range, then the handle returned will be the handle to the 
  678.   highest available port.  For example, if only one output port is 
  679.   available, a wPortNum value of 2 will give you the handle to Port 1. 
  680.   You can use the wm_MD_GetNumberOfOutputPorts to return the number 
  681.   of currently available output ports in PTW.)  
  682.  
  683. wm_MD_GetNumberOfOutputPorts    not used    not used   dwNumberOfPorts
  684.  (this returns the number of currently available output ports in 
  685.   PTW, or 0 if no ports are available)
  686.  
  687. wm_MD_IsPowerTracks  not used not used not used
  688.  (This returns 259.  The PG Music Link component will send this
  689.   message to a window to determine if PowerTracks instead of 
  690.   another application such as the PowerTracks .HLP file.
  691.   If 259 is returned in Msg.Result, then the window is assumed to 
  692.   be the main window of PowerTracks.  If 259 isn't returned then
  693.   the window is assumed to be another program such as the .HLP 
  694.   file.)
  695.  
  696. wm _MD_SendShortMsg wPortNum LDataArray
  697. (This will will let you send MIDI data via PowerTracks in the form
  698. of a short MIDI output message.  WParam should be set to a port 
  699. number (1 to 16) and LParam should be a LongInteger which contains 
  700. the MIDI data in the same 4-byte format as required by MidiOutShortMsg.  
  701. The reason this message is implemented is because WindowsXP won't 
  702. let an .EXE MIDI plugin directly send a MIDI output message using 
  703. the porthandles that were opened in PowerTracks.  In other words XP 
  704. doesn't let apps share the same port handle, so we created this 
  705. message that lets you send a MIDI message by routing it through 
  706. PowerTracks.)
  707.  
  708.  
  709. DIFFERENCES BETWEEN INTERFACING .EXES AND .DLLS TO POWERTRACKS
  710.  
  711. Starting with PTW 3.0b, .EXEs can now be interfaced to PowerTracks.
  712. EXEs are stand-alone applications as opposed to DLLs which are 
  713. libraries that are loaded by EXE applications.  
  714.  
  715. Advantages of using .DLLs as opposed to EXEs:
  716.  
  717. 1) A .DLL can have a dialog that will behave as if it were built-in 
  718. to PTW.  This true if you create a .DLL that has a modal dialog 
  719. (one that doesn't let you switch to another window in the program 
  720. unless you hit OK) An example of this is our $GS.DLL.  When the GS 
  721. dialog pops up, you can't switch to another window in PowerTracks, 
  722. so it won't get obscured.  
  723.  
  724. NOTE: On the other hand, you may want to allow the user to be able 
  725. to switch back and forth between the window of your program so this
  726. is only really an advantage if you want a modal dialog. 
  727.  
  728. 2) DLLs remain in memory until unloaded by PowerTracks so you can
  729. create an editing dialog, such as the $GS.DLL, that stores the 
  730. current settings in memory after the dialog has been closed during
  731. the current session and will re-display them the next time the 
  732. dialog is popped-up during the current PTW session.
  733.  
  734. 3)  You can have a high resolution multimedia timer interrupt in a 
  735. .DLL.  You could have an .EXE that makes use of an MM timer 
  736. interrupt but the .EXE itself would then have use a .DLL for all 
  737. the MM timer interrupt callback routines.  (You can, of course, 
  738. have ordinary (non-multimedia) low resolution windows timer 
  739. routines in an .EXE.)
  740.  
  741. 4) You can call MidiOutShortMsg and MidiOutLongMsg directly with 
  742. the same port handles that are used by PowerTracks.  (Note: We 
  743. created a WM_MD_SendShortMsg that can be used to send a short 
  744. message via PTW.  THis works for both DLLs and EXEs)
  745.  
  746. Advantages to using an .EXE as opposed to a .DLL:
  747.  
  748. 1)  An .EXE is easier to debug than a .DLL.  In fact, Delphi itself 
  749. can't debug a .DLL.  You would have to purchase the latest version 
  750. of Turbo Debugger for Windows.  On the other hand, you could first 
  751. make your program an .EXE, and then, when you've got it debugged, 
  752. you could make it into a .DLL, assuming it doesn't use any 
  753. multimedia timer (MMSYSTEM) routines.
  754.  
  755. 2)  An .EXE could be written in such a way that, instead of being 
  756. launched by PTW, it could be run by itself, and will find PTW (or 
  757. launch PTW if necessary). While this launching feature is a nice 
  758. feature, it is more important that an .EXE be written so that it 
  759. can be launched by Powertracks rather than the other way around. 
  760.  
  761. 3) The PGMusicLink Component.  Our demo .EXE program, EXEDEMO.DPR, 
  762. is a Delphi Project that contains a component called PGMusicLink, 
  763. and is contained in PGLINK.PAS.  The component makes it very easy 
  764. for an .EXE to link to PowerTracks.   You can use it for your .EXE
  765. applications. You don't have to use it, but, if you're using 
  766. Delphi, then using this component makes creating your application 
  767. easier.  Keep in mind that even if you've launched an .EXE from 
  768. within PowerTracks the .EXE still has to locate PTW.EXE's main 
  769. window handle and the PGMusicLink component takes care of this for 
  770. you. 
  771.  
  772. USING THE PGMUSICLINK COMPONENT:
  773.  
  774. The following will explain how you can use the PGMusicLink 
  775. component in your applications.  We've included a demo .EXE program 
  776. written in Delphi, called EXEDEMO.DPR.  All the source code is 
  777. included, so you can study it in addition to this documentation.
  778.  
  779. To use the component, you first load it into the Delphi component 
  780. library using the Options | Install Components command.  This will 
  781. bring up a dialog that will let you add PGLINK.PAS to the component 
  782. library. After you've installed the component, Delphi will 
  783. recompile the component library, and then it will appear in the 
  784. component palette in the 'Samples' page.  You can then click on the 
  785. component and drag it to the main form of the application.  
  786.  
  787. Your application can launch PTW simply by referencing the 
  788. component's MainWinHandle property.  The component takes care of 
  789. issues such as finding PTW if it's already running, launching it if 
  790. necessary, and prompting the user for the path name if necessary. 
  791. If this property is equal to zero, then that means the component 
  792. could not link to PTW.  The component issues error messages to the 
  793. user and gives the user a chance to correct errors such as an 
  794. incorrect path name.  Since the component does all this work, if it 
  795. should turn out that this property is equal to zero (e.g. if your 
  796. window's PGMusicLink component is called PGMusicLink1, and 
  797. PGMusicLink.MainWinHandle = 0) your application can assume the 
  798. component couldn't link and the user has already been informed of 
  799. this, so your program could simply issue one final message such as 
  800. 'Could Not Link To PowerTracks, quitting...' and then simply stop 
  801. executing as our EXEDEMO.DPR application does.
  802.  
  803. You can give the user a chance to link to a different program after
  804. initialization.  For example, if we eventually add linking support 
  805. to other programs such as Band-in-a-Box, then having a 'Choose 
  806. .EXE' button on your main window could let the .EXE be used 
  807. with other programs.  There is a component method called 
  808. PromptUserForExeName which brings up a dialog prompting the user to 
  809. choose a different .EXE to link to, and returns true if the user 
  810. selected a different .EXE name.  If the user has chosen a different 
  811. .EXE, then the component signs out of the currently linked .EXE.  
  812. Your application then just has to reference the MainWinHandle 
  813. property again to obtain the handle to the new .EXE, and if the 
  814. handle is equal to 0 then that means linking to the different .EXE 
  815. failed (and the component has already issues error message and 
  816. given the user a chance to enter a different path name, etc). 
  817.  
  818. If the user is ever prompted for a different .EXE name and presses 
  819. OK, the path of that .EXE will be stored in a file called 
  820. PGLINK.INI which resides in the directory of your application.  
  821. This file will be read by the component the next time your 
  822. application is run. 
  823.  
  824. If we add linking support to other programs besides PTW, and your 
  825. application were meant for use with another program, such as BBW, you 
  826. can change the default name of the .EXE that the component links to 
  827. by editing the ExeName property at design time.  By default, the 
  828. .EXE name is set to 'PTW.EXE'.  You could set it to, say, 'BBW.EXE' 
  829. if we added linking support to BBW and your .EXE were designed to 
  830. link to BBW rather than PowerTracks.
  831.  
  832. In summary, the PGMusicLink component has two properties and one 
  833. method function that you need to be aware of: 
  834.  
  835. 1) The MainWinHandle property which, when referenced by your 
  836. application (e.g TheHandle := PGMusicLink1.MainWinHandle) will 
  837. either obtain the handle to PTW or will return 0 if the component 
  838. couldn't link.  
  839.  
  840. 2) The ExeName property, which can be changed at design time.
  841.  
  842. 3) The PromptUserForExeName Function that you can use to give the 
  843. user a chance to link to a different .EXE after initial linking was 
  844. successful.
  845.  
  846. Here's a list of all the messages with their numeric values:
  847.  
  848. Const wm_MD_BufferNotNeeded = wm_User + 33;
  849. Const wm_MD_GetVersion = wm_User + 200;
  850. Const wm_MD_SetTrackNumber = wm_User + 201;
  851. Const wm_MD_GetTrackNumber = wm_User + 202;
  852. Const wm_MD_GetTrackNumberOfEvents = wm_User + 203;
  853. Const wm_MD_GetHighestTrack = wm_User + 204;
  854. Const wm_MD_DeleteTrackEvent = wm_User + 205;
  855. Const wm_MD_UpdateScreens = wm_User + 206;
  856. Const wm_MD_InsertTrackEvent = wm_User + 207;
  857. Const wm_MD_ModifyTrackEvent = wm_User + 208;
  858. Const wm_MD_GetTrackEvent = wm_User + 209;
  859. Const wm_MD_GetTrackInfo = wm_User + 210;
  860. Const wm_MD_SetTrackInfo = wm_User + 211;
  861. Const wm_MD_GetSongTime = wm_User + 212;
  862. Const wm_MD_SetSongTime = wm_User + 213;
  863. Const wm_MD_Play = wm_User + 214;
  864. Const wm_MD_Stop = wm_User + 215;
  865. Const wm_MD_GetFromValue = wm_User + 216;
  866. Const wm_MD_GetThruValue = wm_User + 217;
  867. Const wm_MD_SetFromValue = wm_User + 218;
  868. Const wm_MD_SetThruValue = wm_User + 219;
  869. Const wm_MD_IsTrackHighlighted = wm_User + 220;
  870. Const wm_MD_GetSongPPQ = wm_User + 221;
  871. Const wm_MD_GetNumberofMeterMapEvents = wm_User + 222;
  872. Const wm_MD_GetMeterMapNumerator = wm_User + 223;
  873. Const wm_MD_GetMeterMapDenominator = wm_User + 224;
  874. Const wm_MD_GetMeterMapTime = wm_User + 225;
  875. Const wm_MD_GetMeterMapMeasure = wm_User + 226;
  876. Const wm_MD_SetMeterMapNumerator = wm_User + 227;
  877. Const wm_MD_SetMeterMapDenominator = wm_User + 228;
  878. Const wm_MD_InsertMeter = wm_User + 229;
  879. Const wm_MD_DeleteMeter = wm_User + 230;
  880. Const wm_MD_GetTempoMapTempoValue = wm_User + 231;
  881. Const wm_MD_GetTempoMapTime = wm_User + 232;
  882. Const wm_MD_SetTempoMapTempoValue = wm_User + 233;
  883. Const wm_MD_GetNumberofTempoMapEvents = wm_User + 234;
  884. Const wm_MD_InsertTempo = wm_User + 235;
  885. Const wm_MD_DeleteTempo = wm_User + 236;
  886. Const wm_MD_GetSongKeySignature = wm_User + 237;
  887. Const wm_MD_SaveUndoTrackData = wm_User + 238;
  888. Const wm_MD_Undo = wm_User + 239;
  889. Const wm_MD_ExeSignIn = wm_User + 258;
  890. Const wm_MD_ExeSignOut = wm_User + 241;
  891. Const wm_MD_SaveFile = wm_User + 242;
  892. Const wm_MD_LoadFile = wm_User + 243;
  893. Const wm_MD_GetCurrentFileName = wm_User + 244;
  894. Const wm_MD_GetCurrentTrack = wm_User + 245;
  895. Const wm_MD_IsPlayBackHappening = wm_User + 246;
  896. Const wm_MD_GetOutputPortHandle = wm_User + 247;
  897. Const wm_MD_GetNumberOfOutputPorts = wm_User + 248;
  898. Const wm_MD_ExeSignIn = wm_User + 258;
  899. Const wm_MD_IsPowerTracks = wm_user + 259;
  900. Const wm_MD_SendShortMsg = wm_user + 260
  901.  
  902. ----------------------End of Document - PTWDLL.TXT--------------
  903.